package com.gtja.beoms.service.impl;

import com.gtja.beoms.dto.FileBO;
import com.gtja.beoms.service.IFTPService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;

@Service
public class FTPServiceImp implements IFTPService {
    private final static Logger logger = LoggerFactory.getLogger(FTPServiceImp.class);
    //业务类型
    private final static String BUSI_TYPE = "qwoms";
    //FTP 服务器IP
    @Value("${uploadFiles.external.ftpHost:10.189.96.93}")
    private String ftpHost;
    //FTP 端口号
    @Value("${uploadFiles.external.ftpPort:21}")
    private String port;
    //FTP 用户名
    @Value("${uploadFiles.external.ftpUserName:f}")
    private String userName;
    //FTP 密码
    @Value("${uploadFiles.external.ftpPassWord:f+cssweb}")
    private String passWord;

    /**
     *
     * @param fileBO
     * @return null即为上传成功,否则为异常信息
     */
    @Override
    public String upload(FileBO fileBO) {
        Map<String, Object> map = new HashMap<>();
        FTPClient ftpClient = new FTPClient();
        try {
            // 1. FTP 连接登录
            ftpClient.connect(ftpHost, Integer.valueOf(port));
            ftpClient.login(userName, passWord);
            int replyCode = ftpClient.getReplyCode();
            if ((!FTPReply.isPositiveCompletion(replyCode))) {
                logger.error("FTP Server [{}] Login Fail,please verify user [{}] and pwd [{}]", ftpHost, userName, passWord);
                ftpClient.disconnect();
                return "FTP 服务器登录失败";
            }

            // 2. 创建FTP目录
            String ftpDir = createFtpDir(ftpClient, fileBO.getBasePath());
            if (StringUtils.isBlank(ftpDir)) {
                return "FTP 创建目录失败";
            }

            // 3. 文件上传
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            if (!ftpClient.storeFile(fileBO.getFileName(), fileBO.getInputStream())) {
                return "FTP 文件上传失败";
            }
            fileBO.getInputStream().close();
            ftpClient.logout();

            // 4.响应数据
            fileBO.setHttpPath(ftpDir);
            fileBO.setModule(BUSI_TYPE);
            fileBO.setModuleName(BUSI_TYPE);

            return null;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ftpClient.isConnected()) {
                    ftpClient.disconnect();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "FTP upload IO Exception";
    }

    /**
     * 创建FTP目录。若目录不存在，则创建新的目录
     */
    private String createFtpDir(FTPClient ftpClient, String basePath) {
        // 1. FTP 目录产生规则
        LocalDate now = LocalDate.now();
        // 创建样式:newsurvey/2020318
        String reDir = BUSI_TYPE + "/" + now.getYear() + now.getMonthValue() + now.getDayOfMonth();
        String absDir = basePath + reDir;

        try {
            // 2.目录不存在，则需要层级目录一级级创建
            if (!ftpClient.changeWorkingDirectory(absDir)) {
                String[] dirs = absDir.split("/");
                String tempPath = "";
                for (String dir : dirs) {
                    if (StringUtils.isBlank(dir)) {
                        continue;
                    }
                    tempPath += "/" + dir;
                    if (!ftpClient.changeWorkingDirectory(tempPath)) {
                        if (!ftpClient.makeDirectory(tempPath)) {
                            logger.error("FTP make directory fail,diretory path is [{}]", tempPath);
                            return null;
                        } else {
                            ftpClient.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            return absDir;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}
